package de.sendorian.app.forumArchive.matcher;

import org.hamcrest.Description;
import org.hamcrest.Factory;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeDiagnosingMatcher;
import org.joda.time.DateTime;
import org.joda.time.Interval;

import de.sendorian.app.forumArchive.domain.Post;
import de.sendorian.app.forumArchive.domain.Topic;


public class ForumMatcher {

    @Factory
    public static Matcher<Post> matchesDateInterval(final DateTime start, final DateTime end) {
        final DateTime startNormalized = start.withTime(0, 0, 0, 0);
        final DateTime realEnd;
        if (end == null) {
            realEnd = new DateTime();
        } else {
            // set to midnight the next day
            realEnd = end.plusDays(1).withTime(0, 0, 0, 0);
        }

        return new TypeSafeDiagnosingMatcher<Post>() {
            private Post post;


            @Override
            protected boolean matchesSafely(Post item, Description mismatchDescription) {
                post = item;

                Interval interval = new Interval(startNormalized, realEnd);
                DateTime lastChangeDate = new DateTime(post.getPostDate());
                if (interval.contains(lastChangeDate))
                    return true;
                return false;
            }


            public void describeTo(Description description) {
                description.appendText(" that post ");
                description.appendValue(post);
                description.appendText(" is posted between ");
                description.appendValue(start);
                description.appendText(" and ");
                description.appendValue(realEnd);
            }

        };
    }


    @Factory
    public static Matcher<Topic> matchesDateIntervalUntilNow(final DateTime start) {
        final DateTime startNormalized = start.withTime(0, 0, 0, 0);

        return new TypeSafeDiagnosingMatcher<Topic>() {
            private Topic topic;


            @Override
            protected boolean matchesSafely(Topic item, Description mismatchDescription) {
                topic = item;

                Interval interval = new Interval(startNormalized, new DateTime());
                DateTime lastChangeDate = new DateTime(topic.getLastPost());
                if (interval.contains(lastChangeDate))
                    return true;
                return false;
            }


            public void describeTo(Description description) {
                description.appendText(" that topic ");
                description.appendValue(topic);
                description.appendText(" has last post between ");
                description.appendValue(start);
                description.appendText(" and ");
                description.appendValue(new DateTime());
            }

        };
    }
}
